package com.rain.builder;

import com.rain.bean.FieldInfo;
import com.rain.bean.TableInfo;
import com.rain.utils.*;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;

public class BuildPo {

    private static final Logger logger = LoggerFactory.getLogger(BuildPo.class);

    public static void execute(TableInfo tableInfo) throws IOException {
        File folder = new File(Constants.PACKAGE_ENTITY_PATH);
        if(!folder.exists()){
            folder.mkdirs();
        }

        File file = new File(folder,tableInfo.getBeanName() + ".java");

        try{
            file.createNewFile();
        }catch(IOException e){
            e.printStackTrace();
        }

        OutputStream outputStream = null;
        OutputStreamWriter outputStreamWriter = null;
        BufferedWriter bufferedWriter = null;

        try{
            outputStream = new FileOutputStream(file);
            outputStreamWriter = new OutputStreamWriter(outputStream,"UTF-8");
            bufferedWriter = new BufferedWriter(outputStreamWriter);
            // 基本模版
            bufferedWriter.write("package " + Constants.PACKAGE_ENTITY + ";");
            bufferedWriter.newLine();
            bufferedWriter.newLine();
            bufferedWriter.write("import java.io.Serializable;");
            bufferedWriter.newLine();

            // 判断是否添加日期类
            if(tableInfo.getHaveDate() || tableInfo.getHaveDateTime()){
                bufferedWriter.write("import java.util.Date;");
                bufferedWriter.newLine();
                bufferedWriter.write(Constants.BEAN_DATE_FORMAT_CLASS + ";");
                bufferedWriter.newLine();
                bufferedWriter.write(Constants.BEAN_DATE_UNFORMAT_CLASS + ";");
                bufferedWriter.newLine();
                bufferedWriter.write("import " + Constants.PACKAGE_ENUM +".DateTimePatternEnum;");
                bufferedWriter.newLine();
                bufferedWriter.write("import " + Constants.PACKAGE_UTILS +".DateUtil;");
                bufferedWriter.newLine();

            }

            // 判断是否添加忽略的属性类
            Boolean haveIgnoreBean = false;
            for (FieldInfo fieldInfo: tableInfo.getFieldList()) {
                if(ArrayUtils.contains(Constants.IGNORE_BEAN_TOJSON_FILED.split(","),fieldInfo.getPropertyName())) {
                    haveIgnoreBean = true;
                    break;
                }
            }
            if(haveIgnoreBean) {
                bufferedWriter.write(Constants.IGNORE_BEAN_TOJSON_CLASS + ";");
                bufferedWriter.newLine();
            }

            // 判断是否添加精确小数类
            if(tableInfo.getHaveBigDecimal()){
                bufferedWriter.write("import java.math.BigDecimal;");
                bufferedWriter.newLine();
            }
            bufferedWriter.newLine();

            // 构建类注释
            BuildComment.createClassComment(bufferedWriter,tableInfo.getComment());
            bufferedWriter.write("public class " + tableInfo.getBeanName() + " implements Serializable {");
            bufferedWriter.newLine();
            bufferedWriter.newLine();
            // 属性
            for (FieldInfo fieldInfo: tableInfo.getFieldList()) {
                // 添加注释
                BuildComment.createFieldComment(bufferedWriter,fieldInfo.getComment());

                // 判断是否添加日期格式序列化，日期格式反序列化 注解
                if(ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES,fieldInfo.getSqlType())) {
                    bufferedWriter.write("\t" + String.format(Constants.BEAN_DATE_FORMAT_EXPRESSION, DateUtils.YYYY_MM_DD_HH_MM_SS));
                    bufferedWriter.newLine();
                    bufferedWriter.write("\t" + String.format(Constants.BEAN_DATE_UNFORMAT_EXPRESSION, DateUtils.YYYY_MM_DD_HH_MM_SS));
                    bufferedWriter.newLine();
                }

                // 判断是否添加日期格式序列化，日期格式反序列化 注解
                if(ArrayUtils.contains(Constants.SQL_DATE_TYPES,fieldInfo.getSqlType())) {
                    bufferedWriter.write("\t" + String.format(Constants.BEAN_DATE_FORMAT_EXPRESSION, DateUtils.YYYY_MM_DD));
                    bufferedWriter.newLine();
                    bufferedWriter.write("\t" + String.format(Constants.BEAN_DATE_UNFORMAT_EXPRESSION, DateUtils.YYYY_MM_DD));
                    bufferedWriter.newLine();
                }

                // 判断是否添加忽略的属性注解
                if(ArrayUtils.contains(Constants.IGNORE_BEAN_TOJSON_FILED.split(","),fieldInfo.getPropertyName())) {
                    bufferedWriter.write("\t" + Constants.IGNORE_BEAN_TOJSON_EXPRESSION);
                    bufferedWriter.newLine();
                }

                bufferedWriter.write("\tprivate " + fieldInfo.getJavaType() + " " + fieldInfo.getPropertyName() + ";");
                bufferedWriter.newLine();
                bufferedWriter.newLine();
            }

            // get set 方法
            for (FieldInfo fieldInfo: tableInfo.getFieldList()) {
                String tempField = StringUtils.uperCaseFirstLetter(fieldInfo.getPropertyName());
                bufferedWriter.write("\tpublic void set" + tempField + "(" + fieldInfo.getJavaType() + " " + fieldInfo.getPropertyName() + ")  { ");
                bufferedWriter.newLine();
                bufferedWriter.write("\t\tthis." + fieldInfo.getPropertyName() +" = " + fieldInfo.getPropertyName() + ";");
                bufferedWriter.newLine();
                bufferedWriter.write("\t}");
                bufferedWriter.newLine();
                bufferedWriter.newLine();


                bufferedWriter.write("\tpublic " + fieldInfo.getJavaType() + " get" + tempField + "( ) { ");
                bufferedWriter.newLine();
                bufferedWriter.write("\t\treturn this." + fieldInfo.getPropertyName() + ";");
                bufferedWriter.newLine();
                bufferedWriter.write("\t}");
                bufferedWriter.newLine();
                bufferedWriter.newLine();
            }

            // 重写toString方法
            StringBuffer stringBuffer = new StringBuffer();
            Integer i = 0;
            for(FieldInfo fieldInfo : tableInfo.getFieldList()) {
                i++;

                String properNameVal = fieldInfo.getPropertyName();
                if(ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES,fieldInfo.getSqlType())){
                    properNameVal = "DateUtil.format(" + properNameVal + ", DateTimePatternEnum.YYYY_MM_DD_HH_MM_SS.getPattern())";
                }else if(ArrayUtils.contains(Constants.SQL_DATE_TYPES,fieldInfo.getSqlType())){
                    properNameVal = "DateUtil.format(" + properNameVal + ", DateTimePatternEnum.YYYY_MM_DD.getPattern())";
                }

                if (i == tableInfo.getFieldList().size()) {
                    stringBuffer.append("\"" + fieldInfo.getPropertyName() + ": \" + " + properNameVal + " + \" } \"");
                }else if(i == 1) {
                    stringBuffer.append("\" " + StringUtils.uperCaseFirstLetter(tableInfo.getBeanName()) + " { " + fieldInfo.getPropertyName() + ": \" + " + properNameVal + " + ");
                }else {
                    stringBuffer.append("\"" + fieldInfo.getPropertyName() + ": \" + " + properNameVal + " + ");
                }

                if(i < tableInfo.getFieldList().size()) {
                    stringBuffer.append("\", \" + ");
                }
            }


            bufferedWriter.write("\t@Override");
            bufferedWriter.newLine();
            bufferedWriter.write("\tpublic String toString()  {");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\treturn " + stringBuffer + ";");
            bufferedWriter.newLine();
            bufferedWriter.write("\t}");
            bufferedWriter.newLine();


            bufferedWriter.write("}");
            bufferedWriter.flush();
        }catch (Exception e){
            logger.info("创建po失败", e.getMessage());
            e.printStackTrace();
        }finally {
            if(bufferedWriter != null) {
                bufferedWriter.close();
            }
            if(outputStreamWriter != null) {
                outputStreamWriter.close();
            }
            if(outputStream != null) {
                outputStream.close();
            }
        }



    }
}
